//Client.java  
//
//Copyright (C) 2008 Devon Mizelle  
//  
//This program is distributed in the hope that it will be useful,  
//but WITHOUT ANY WARRANTY; without even the implied warranty of  
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
//GNU General Public License for more details.  
//  
//You should have received a copy of the GNU General Public License  
//along with this program.  If not, see <http://www.gnu.org/licenses/>.
package hermes;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.io.File;
import java.net.ServerSocket;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.ProgressMonitorInputStream;
/**
 * 
 * 
 * @author Devon Mizelle 
 */
public class Client
{
    Socket socket = null;
    ObjectOutputStream oos = null;
    ObjectInputStream ois = null;
    FileInputStream fis = null;
    FileOutputStream fos = null;
    File file = null;
    User user = null;
    PrivateKey privateKey = null;
    PublicKey publicKey = null;
    Scanner rdr = null;
    String[] message = null;
    UserMap userMap = null;
    Listener listener = null;
    public Client(){
    }
    
    public Client(JFrame parent){
        listener = new Listener(parent);
        listener.start();
    }
    
    public void init(String id){
        try{       
            
            file = new File("user.info");
            if(!file.exists()){
                file.createNewFile();    
                fos = new FileOutputStream(file);
                oos = new ObjectOutputStream(fos);
                user = new User(id);
                oos.writeObject(user);
                oos.close();
                fos.close();
                }
            fis = new FileInputStream(file);
            ois = new ObjectInputStream(fis);
            user = (User) ois.readObject();
            ois.close();
            fis.close();
        }
        catch(java.io.NotSerializableException e){
            
        }
        catch(Exception e){
            e.printStackTrace();
        }
        privateKey = (PrivateKey) user.get("privateKey");
        publicKey = (PublicKey) user.get("publicKey");
    
    }
    
    public void connect(String hostname, String port) throws Exception {
        try{    
            socket = new Socket(hostname, Integer.parseInt(port));
        
            oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(user); //send userinfo to server.
            ois = new ObjectInputStream(socket.getInputStream());
            System.out.println(ois.readObject());
                        
        }
        catch(Exception e){
            throw e;
        }
    }
    
    public UserMap getNewUserMap() throws Exception{
        try{oos.writeObject("GET USERMAP");}catch(Exception e){ throw e; }
        userMap = (UserMap) ois.readObject();
        return userMap;
    }
    
    public boolean userFileExists(){
        File file = new File("user.info");
        return file.exists();
    
    }
    
    public int sendFile(String fromUsername, String ip, String filename, FileWrap fw) throws Exception{
        ois = null; fis = null; oos = null; fos = null;
        try{
            long length = fw.getLength();
            Socket sendingSocket = new Socket(ip, 9002);
            oos = new ObjectOutputStream(sendingSocket.getOutputStream());
            oos.writeObject("INC " + filename);
            oos.writeObject("FROM " + fromUsername);
            oos.writeObject("LEN" + length);
            oos.writeObject(fw);
            return 0;
        }
        catch(Exception e){
            throw e;
        }
       
    }
    private class Listener extends Thread {
        ServerSocket listenSocket = null;
        FileOutputStream fos = null;
        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        JFrame parent = null;
        public Listener(JFrame parent) {
            this.parent = parent;
        }
        public void showException(Exception e, JFrame parent){
            e.printStackTrace();
            javax.swing.JOptionPane.showMessageDialog((java.awt.Frame) parent,
                        e.toString(),
                        "Exception Caught!",
                        javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        public void run(){
            try{ 
                listenSocket = new ServerSocket(9002);
                Socket socket = listenSocket.accept();
            }
            catch(Exception e){
                showException(e, parent);
            }
            
            handler(socket, parent);
        }
        public void handler(Socket socket, JFrame parent){
            try{
                ois = new ObjectInputStream(socket.getInputStream());
            
                String inc = (String) ois.readObject();
                inc = inc.replace("INC ", "");
                String from = (String) ois.readObject();
                from = from.replace("FROM ", "");
                String length = (String) ois.readObject();
                length = length.replace("LEN ", "");
                fos = new FileOutputStream(from);
                oos = new ObjectOutputStream(fos);
                ObjectInputStream oispm = new ObjectInputStream(new ProgressMonitorInputStream(parent, "Receiving File...", ois));
                FileWrap fw = (FileWrap) oispm.readObject();
                oos.write(fw.getFile());
                oos.flush(); fos.flush(); ois.close(); oispm.close();
            
            }
            catch(Exception e){
                showException(e, parent);
            }
        }
    }
}